package cn.iocoder.yudao.module.erp.service.invoice;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.invoice.vo.InvoicePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.invoice.vo.InvoiceSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.invoice.InvoiceDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.invoiceintegration.InvoiceIntegrationDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purpurchaseorder.PurPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.mysql.invoice.InvoiceMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.invoicechecklist.InvoiceCheckListMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.invoicechecklistitem.InvoiceCheckListItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.invoiceintegration.InvoiceIntegrationMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpSupplierMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.purpurchaseorder.PurPurchaseOrderMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * ERP 发票 Service 实现类
 *
 * @author 源码
 */
@Service
@Validated
public class InvoiceServiceImpl implements InvoiceService {

    @Resource
    private InvoiceMapper invoiceMapper;
    @Resource
    private InvoiceCheckListItemMapper invoiceCheckListItemMapper;
    @Resource
    private InvoiceCheckListMapper invoiceCheckListMapper;
    @Resource
    private ErpNoRedisDAO noRedisDAO;
    @Resource
    private InvoiceIntegrationMapper invoiceIntegrationMapper;
    @Resource
    private PurPurchaseOrderMapper purPurchaseOrderMapper;
    @Resource
    private ErpSupplierMapper supplierMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createInvoice(InvoiceSaveReqVO createReqVO) {
        List<PurPurchaseOrderDO> purPurchaseOrderDOS = createReqVO.getPurPurchaseOrderDOS();
        List<String> ids = purPurchaseOrderDOS.stream().map(purPurchaseOrderDO -> purPurchaseOrderDO.getId()).collect(Collectors.toList());
        List<PurPurchaseOrderDO> listByIds = purPurchaseOrderMapper.getListByIds(ids);
        List<String> IntegrateIds = listByIds.stream().map(purPurchaseOrderDO -> purPurchaseOrderDO.getOrderIntegrateId()).collect(Collectors.toList());
        boolean containsZero = IntegrateIds.contains("0");
        if (!containsZero){
            String  orderIntegrateId = null;
            for (String integrateId : IntegrateIds) {
                orderIntegrateId = integrateId;
            }
            // 发票表插入
            InvoiceDO invoice = BeanUtils.toBean(createReqVO, InvoiceDO.class);
            invoice.setOrderIntegrateId(orderIntegrateId);
            invoiceMapper.insert(invoice);
        }else {
            InvoiceIntegrationDO invoiceIntegrationDO = new InvoiceIntegrationDO();
            // 计算订单数量
            int orderNum = 0;
            // 计算订单总金额
            BigDecimal totalPrice = new BigDecimal("0");
            //  发票整合单生成，并校验唯一性
            String no = noRedisDAO.generate(ErpNoRedisDAO.ICVOICE_INTEGRATE_ORDER_NO_PREFIX);
            if (invoiceIntegrationMapper.selectByNo(no) != null) {
                throw exception(ICVOICE_INTEGRATE_CHECK_NO_EXISTS);
            }

            orderNum = purPurchaseOrderDOS.size();
            for (PurPurchaseOrderDO purPurchaseOrderDO : purPurchaseOrderDOS) {
                totalPrice = totalPrice.add(purPurchaseOrderDO.getTotalPrice());
            }
            // 设置集成ID
            invoiceIntegrationDO.setIntegrationId(no);
            // 设置订单号
            invoiceIntegrationDO.setOrderNum(BigDecimal.valueOf(orderNum));
            // 设置订单总价
            invoiceIntegrationDO.setOrderTotalPric(totalPrice);
            invoiceIntegrationDO.setSupplierId(createReqVO.getSupplierId());
            // 根据供应商差部门
            ErpSupplierDO erpSupplierDO = supplierMapper.selectById(createReqVO.getSupplierId());
            if (erpSupplierDO != null){
                invoiceIntegrationDO.setDeptId(erpSupplierDO.getDeptId());
            }

            // 插入数据
            invoiceIntegrationMapper.insert(invoiceIntegrationDO);

            for (PurPurchaseOrderDO purPurchaseOrderDO : purPurchaseOrderDOS) {
                // 设置整合发票ID
                purPurchaseOrderDO.setOrderIntegrateId(invoiceIntegrationDO.getId());
            }
            purPurchaseOrderMapper.updateBatch(purPurchaseOrderDOS);
            // 发票表插入
            InvoiceDO invoice = BeanUtils.toBean(createReqVO, InvoiceDO.class);
            invoice.setOrderIntegrateId(invoiceIntegrationDO.getId());
            invoiceMapper.insert(invoice);
        }

        // 返回
        return null;
    }

    @Override
    public void updateInvoice(InvoiceSaveReqVO updateReqVO) {
        // 校验存在
        validateInvoiceExists(updateReqVO.getId());
        // 更新
        InvoiceDO updateObj = BeanUtils.toBean(updateReqVO, InvoiceDO.class);
        invoiceMapper.updateById(updateObj);
    }

    @Override
    public void deleteInvoice(Long id) {
        // 校验存在
        validateInvoiceExists(id);
        // 删除
        invoiceMapper.deleteById(id);
    }

    private void validateInvoiceExists(Long id) {
        if (invoiceMapper.selectById(id) == null) {
            throw exception(INVOICE_NOT_EXISTS);
        }
    }

    @Override
    public InvoiceDO getInvoice(Long id) {
        return invoiceMapper.selectById(id);
    }

    @Override
    public PageResult<InvoiceDO> getInvoicePage(InvoicePageReqVO pageReqVO) {
        return invoiceMapper.selectPage(pageReqVO);
    }
    /**
     * 根据发票整合单编号查询发票信息
     * @param checkInvoiceId
     * @return
     */
    @Override
    public List<InvoiceDO> getInvoiceByCheckInvoiceId(String checkInvoiceId) {
        //        根据整合单编号查询发票信息
        return invoiceMapper.selectList(new QueryWrapperX<InvoiceDO>().eq("order_integrate_id", checkInvoiceId));
    }

    @Override
    public List<InvoiceDO> getInvoiceByOrderIntegrateId(InvoicePageReqVO pageReqVO) {
        List<String> numbers = pageReqVO.getNumbers();
        List<InvoiceDO> invoiceDOS = invoiceMapper.getByOrderIntegrateIds(numbers);
        return invoiceDOS;
    }

    /**
     * 根据随货同行单的采购单编号数组 查询发票列表
     * @param purchaseOrderIds
     * @return
     */
    @Override
    public List<InvoiceDO> getInvoiceListByPurchaseOrderIds(List<String> purchaseOrderIds) {
        if (purchaseOrderIds == null || purchaseOrderIds.size() == 0){
//            "采购单编号数组为空"
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
//        根据采购单编号查询采购单
        List<PurPurchaseOrderDO> purchaseOrders = purPurchaseOrderMapper.selectList(new QueryWrapperX<PurPurchaseOrderDO>().in("id", purchaseOrderIds));
        List<String> collect = purchaseOrders
                .stream().map(PurPurchaseOrderDO::getOrderIntegrateId).collect(Collectors.toList());
//        根据采购单中orderIntegrateId查询发票整合单
        List<InvoiceIntegrationDO> invoiceIntegrations = invoiceIntegrationMapper.selectList(new QueryWrapperX<InvoiceIntegrationDO>()
                .in("id", collect));
//        根据发票整合单中的id查询发票
        List<InvoiceDO> invoiceDOS = invoiceMapper.selectList(new QueryWrapperX<InvoiceDO>()
                .in("order_integrate_id", invoiceIntegrations
                        .stream().map(InvoiceIntegrationDO::getId).collect(Collectors.toList())));
        return invoiceDOS;
    }


}